package webmarket.controller;

import java.io.File;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.Level;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import org.springframework.web.servlet.ModelAndView;

import webmarket.common.DataTablesParamUtility;
import webmarket.common.DatatableResponse;
import webmarket.common.MarkerController;
import webmarket.common.ShopcategoryController;
import webmarket.common.MarkerController.MarkerTypes;
import webmarket.common.UserInfoMessages;
import webmarket.controller.transferobjects.JQueryDataTableParamModel;
import webmarket.controller.transferobjects.MerchandiseTO;
import webmarket.jpacontrollers.ShopJpaController;
import webmarket.jpacontrollers.UserJpaController;
import webmarket.model.Merchandise;
import webmarket.model.User;

@Controller
@RequestMapping("/shop")
public class ShopController extends ControllerBase {
	private static final String pictureBasePath = "resources/img/merchandise/";

	@RequestMapping(value = "/new", method = RequestMethod.GET)
	public ModelAndView newMerchandise(ModelMap model, HttpServletRequest request) {
		logger.entry();
		model.put("categoryOptions", ShopcategoryController.getLeafsForSelect());
		return new ModelAndView("shop_new", model);
	}

	@RequestMapping(value = "/new", method = RequestMethod.POST)
	public String newMerchandise_create(@RequestParam(required = true) String name,
			@RequestParam(required = true) int categoryId,
			@RequestParam(required = true) String description,
			@RequestParam(required = true) int price) {
		logger.entry();
		Merchandise merch = new ShopJpaController().createMerchandise(name, description, price, categoryId);
		logger.info(MarkerController.getMarker(MarkerTypes.CREATE), "A felhasználó új hirdetést hozott létre");
		logger.exit(merch);
		return "redirect:/shop/sales";
	}

	@RequestMapping(value = "/picture/upload", method = RequestMethod.POST)
	public String uploadPicture(@RequestParam int merchandiseId, @RequestParam CommonsMultipartFile picture, HttpServletRequest request) {
		logger.entry();
		String absFilePath = "";
		if (picture != null) {
			String basePath = getBasePath(request);
			FileOutputStream outputStream = null;
			String filename = picture.getFileItem().getName();
			String filePath = basePath + merchandiseId + filename.substring(filename.lastIndexOf('.'));
			try {
				File file = new File(filePath);
				absFilePath = file.getAbsolutePath();
				outputStream = new FileOutputStream(file);
				outputStream.write(picture.getFileItem().get());
				outputStream.close();
			} catch (Exception e) {
				logger.catching(Level.DEBUG, e);
			}
		}
		new ShopJpaController().refreshModDate(merchandiseId);
		logger.info(MarkerController.getMarker(MarkerTypes.PICTURE), "A felhasználó feltöltött egy képet a " + merchandiseId + " ID-jú hirdetéshez.");
		logger.exit(absFilePath);
		return "redirect:/profile/sales";
	}

	/**
	 * @param request
	 * @return
	 */
	private String getBasePath(HttpServletRequest request) {
		String basePath = request.getSession().getServletContext().getRealPath("/") + pictureBasePath;
		File baseDir = new File(basePath);
		if (!baseDir.exists()) {
			baseDir.mkdirs();
		}
		return basePath;
	}

	@RequestMapping(value = "/sales")
	public ModelAndView shop_main(ModelMap model) {
		model.put("categoryOptions", ShopcategoryController.getForSelect());
		return new ModelAndView("shop_sales", model);
	}

	@RequestMapping(value = "/sales/getSales")
	public @ResponseBody
	DatatableResponse<MerchandiseTO> sales_merch(HttpServletRequest request) {
		JQueryDataTableParamModel param = DataTablesParamUtility.getParam(request);
		logger.debug(param.toString());
		DatatableResponse<MerchandiseTO> response = new DatatableResponse<MerchandiseTO>(param);
		String sortCol = param.getSortColumnName();
		String sortDir = param.sSortDirection;
		int limit = param.iDisplayLength;
		int offset = param.iDisplayStart;
		String nameLike = request.getParameter("name");
		String categoryIdString = request.getParameter("categoryId");
		Integer categoryId = null;
		if (!StringUtils.isBlank(categoryIdString) && !categoryIdString.equals("0")) {
			categoryId = Integer.parseInt(categoryIdString);
		}
		String priceFromString = request.getParameter("priceFrom");
		Integer priceFrom = null;
		if (!StringUtils.isBlank(priceFromString)) {
			priceFrom = Integer.parseInt(priceFromString);
		}
		Integer priceTo = null;
		String priceToString = request.getParameter("priceTo");
		if (!StringUtils.isBlank(priceToString)) {
			priceTo = Integer.parseInt(priceToString);
		}
		ShopJpaController sjc = new ShopJpaController();
		List<Merchandise> merches = sjc.getMerchandises(categoryId, null, nameLike, priceFrom, priceTo, sortCol, sortDir, limit, offset);
		response.setData(MerchandiseTO.convert(merches), sjc.getCount(), sjc.getCount(categoryId, null, nameLike, priceFrom, priceTo));
		logger.debug(response.toString());
		logger.exit();
		return response;
	}

	@RequestMapping(value = "/sales/{merchId}")
	public ModelAndView sales_getMerch(@PathVariable final int merchId, ModelMap model, HttpServletRequest request) {
		ShopJpaController sjc = new ShopJpaController();
		MerchandiseTO to = new MerchandiseTO(sjc.find(merchId));
		String basePath = getBasePath(request);
		String fileName = getFileName(merchId, basePath);
		boolean picExists = fileName != null;
		if (picExists) {
			model.put("filePath", "/" + pictureBasePath + fileName);
		}
		model.put("merch", to);
		model.put("picExists", picExists);
		Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
		if (authentication.isAuthenticated()) {
			User currentUser = new UserJpaController().getCurrent();
			model.put("currentUserMoney", currentUser.getMoney());
			model.put("showBuyButton", !currentUser.getUsername().equals(to.getUsername()));
		} else {
			model.put("showBuyButton", false);
		}
		return new ModelAndView("sales_merch", model);
	}

	@RequestMapping(value = "/sales/buy")
	public String sales_buy(@RequestParam int merchId) {
		new ShopJpaController().buy(merchId);
		logger.info(MarkerController.getMarker(MarkerTypes.SELL), "A felhasználó megvette a " + merchId + " ID-jú hirdetést.");
		return "redirect:/shop/sales";
	}

	@RequestMapping(value = "/delPicture")
	public @ResponseBody
	String[] sales_delPicture(@RequestParam final int merchId, HttpServletRequest request) {
		String[] retVal = new String[2];
		String basePath = getBasePath(request);
		String fileName = getFileName(merchId, basePath);
		if (fileName == null) {
			retVal[0] = "warning";
			retVal[1] = UserInfoMessages.PICTURE_DELETE_WARNING;
		} else {
			File file = new File(basePath + fileName);
			if (file.delete()) {
				retVal[0] = "success";
				retVal[1] = UserInfoMessages.PICTURE_DELETE_SUCCESS;
			} else {
				retVal[0] = "error";
				retVal[1] = UserInfoMessages.PICTURE_DELETE_ERROR;
			}
		}
		return retVal;
	}

	/**
	 * @param merchId
	 * @param basePath
	 * @return
	 */
	private String getFileName(final int merchId, String basePath) {
		File baseDir = new File(basePath);
		String[] files = baseDir.list(new FilenameFilter() {
			@Override
			public boolean accept(File dir, String name) {
				return name.startsWith(merchId + ".");
			}
		});
		if (files.length == 0) {
			return null;
		}
		return files[0];
	}
}
